package cn.fz.redisdemo01.service;

import cn.fz.redisdemo01.domain.dto.UserDto;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

/**
 * 4 使用自定义的缓存区域
 * 在代码中使用这些自定义的缓存区域时，你可以通过 @Cacheable 注解指定不同的缓存名称。
 *
 * 6. 总结
 * 通过 RedisCacheManager 和 RedisCacheConfiguration，你可以为不同的缓存区域设置不同的 TTL、序列化策略、以及缓存行为。这样可以根据不同的业务场景调整缓存的生命周期，优化应用的性能。
 *
 * 为了更进一步完整代码，可以将缓存名称和对应有效期放入都配置文件中，更有利于线上环境根据实际情况调整缓存有效期，示例如下
 * 原文链接：https://blog.csdn.net/u014390502/article/details/142714655
 */
@Service
public class User2Service {
    // 当方法第一次调用时，结果将被缓存起来，之后相同参数的调用将直接从缓存中获取数据
    @Cacheable(value = "user", key = "#p0")
    public UserDto getUserById(Long id) {
        // 模拟数据库查询操作
        System.out.println("Fetching user with id: " + id);
        return new UserDto(id, "User" + id);
    }

    // 使用短生命周期的缓存配置（1分钟）
    @Cacheable(value = "shortLivedCache", key = "#p0")
    public UserDto getShortLivedUserById(Long id) {
        return findUserInDatabase(id);
    }

    // 使用长生命周期的缓存配置（1小时）
    @Cacheable(value = "longLivedCache", key = "#p0")
    public UserDto getLongLivedUserById(Long id) {
        return findUserInDatabase(id);
    }

    // 使用 JSON 序列化的缓存（30分钟）
    @Cacheable(value = "jsonCache", key = "#p0")
    public UserDto getJsonSerializedUserById(Long id) {
        return findUserInDatabase(id);
    }

    private UserDto findUserInDatabase(Long userId) {
        // 模拟数据库查找
        return new UserDto(userId, "John Doe");
    }
}
